package com.yn.module.material.utils.xls;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.yn.common.utils.ex.Assert;
import com.yn.module.material.utils.ErrorCode;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.List;
import java.util.Map;

/**
 * @description: excel操作接口
 * @author: zq
 * @create: 2021-06-09 14:01  
 * @since: 1.0.0
 * @copyright (C), 2020, 北京望海康信科技有限公司.All rights reserved.
 */

public interface ExcelService {

    /**
     * 按照指定的类型校验导入的数据的指定行，当校验失败时，按行抛出异常
     *
     * @param headLines 标题行的行数
     * @param dto
     * @param list
     */
    void checkExcel(Map<String, Object> selfParams, int headLines, ExcelDTO dto, List<Object> list);

    /**
     * 对导入的数据进行保存
     *
     * @param dto
     * @param list
     * @throws Exception
     */
    void saveExcelData(Map<String, Object> selfParams, ExcelDTO dto, List<Object> list) throws Exception;


    /**
     * 获取Excel数据信息，并进行数据导入处理
     *
     * @param selfParams 自定义从controller传递给对应操作的参数
     * @param dto        文件上传参数dto
     * @param file       待处理的Excel文件
     * @throws Exception
     */
    default void importExcelData(Map<String, Object> selfParams, ExcelDTO dto, MultipartFile file) throws Exception {
        ExcelEntity excelEntity = ExcelStrategyFactory.getExcelImportExportInfo(dto.getType());
        //获取文件流
        InputStream is = file.getInputStream();
        try {
            //获取文件后缀
            String original = file.getOriginalFilename();
            String suffix = original.substring(original.lastIndexOf("."));

            //创建工作薄
            Workbook workbook = ".xlsx".equalsIgnoreCase(suffix) ? new XSSFWorkbook(is) : new HSSFWorkbook(is);
            //获取Exce所有Sheet页索引
            int sheetLength = workbook.getNumberOfSheets();
            // check excel sheets
            ExcelService importService = excelEntity.getSvc();
            // 获取当前上传的Excel中需要读取的sheet索引列表
            Assert.isTrue(sheetLength >= excelEntity.getSheetIndex(), ErrorCode.xls_idx_err);
            ImportParams params = new ImportParams();
            params.setHeadRows(excelEntity.getImportHeaderLines());
            List<Object> retList = ExcelImportUtil.importExcel(file.getInputStream(), excelEntity.getImportClz(), params);
            // 校验数据
            Assert.isNotNull("数据行不允许为空", retList);
            importService.checkExcel(selfParams, excelEntity.getImportHeaderLines(), dto, retList);
            // 导入数据
            importService.saveExcelData(selfParams, dto, retList);

        } finally {
            if (null != is) {
                is.close();
            }
        }
    }
}